﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using NativeWifi;
using System.Net;
using System.Windows.Threading;
using Avarton_Scanner.Logging;
using System.Threading;
using Microsoft.Win32;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Ethernet;
using Avarton_Scanner.Connection;
using System.Net.NetworkInformation;
using System.Data;
using Avarton_Scanner.Tools;

namespace Avarton_Scanner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static String applicationName = "MainWindow.xaml";        
        int timer = 180; //180 seconds
        Boolean databaseOk = false;

        String selectedSSID;
        WlanClient.WlanInterface selectedWlanAdapter;
        IPAddress selectedWlanAdapterSubnetMask;
        String connectedSSID;
        int countNetworks = 0;
        int countNetworkCards = 0;
        int countSecondsScanning;
        int countPacketBytes = 0;
        int maximumPacketsToCapture = 0; //0 for unlimited
        
        Logger log = new Logger();
        Random random = new Random();
        DatabaseClass db = new DatabaseClass();
        
        List<Network> networkArray = new List<Network>();
        List<WlanClient.WlanInterface> adapterArray = new List<WlanClient.WlanInterface>();
        List<Client> clientsArray = new List<Client>();
        List<String> profileArray = new List<String>();
        LivePacketDevice sniffAdapter = null;
        PacketCommunicator communicator = null;
        Thread draad = null;
        
        //set a timer for auto scan for networks
        DispatcherTimer dispatcherTimer = new DispatcherTimer();
        //set a timer for counting scanning time
        DispatcherTimer packetTimer = new DispatcherTimer();
                

        public MainWindow()
        {
            InitializeComponent();            
        }

        #region Minimize, About and Close buttons
        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                DragMove();
            }
            catch (Exception)
            {
                //do nothing
            }
        }

        private void btnClose_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void btnMinimize_MouseDown(object sender, MouseButtonEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void btnAbout_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //open up the "about window"
            var newWindow = new About();
            newWindow.ShowDialog();
        }
        #endregion
        
        static string GetStringForSSID(Wlan.Dot11Ssid ssid)
        {
            return Encoding.ASCII.GetString(ssid.SSID, 0, (int)ssid.SSIDLength);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                //first check if WinPcap is installed, name to check is: "WinPcapInst"
                if (!IsApplictionInstalled("WinPcapInst"))
                {
                    Application.Current.MainWindow.Hide();
                    var newWindow = new WinPcap();
                    newWindow.ShowDialog();
                }
                
                //set application title
                lblApplicationName.Content = "Avarton Scanner";
                WlanClient wlanClient = new WlanClient();
                imgScanning.Visibility = Visibility.Hidden;

                //scan for wlan network adapters and save them
                foreach (WlanClient.WlanInterface wlanIface in wlanClient.Interfaces)
                {
                    //add every adapter to a array
                    adapterArray.Add(wlanIface);
                    //add every adapter name to combobox
                    cboxAdapters.Items.Add(wlanIface.InterfaceName.ToString());
                    //count network cards
                    countNetworkCards++;
                }


                //if no adapter is found display error and shut down the application
                if (countNetworkCards <= 0)
                {
                    MessageBox.Show("No wireless network cards found in your machine or maybe they are disabled?");
                    Application.Current.Shutdown();
                }

                lblAdapters.Content = String.Format("Network adapters ({0}): ", countNetworkCards.ToString());

                //set up network timer properties
                dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 1);

                //check if there can be a connection made with the database
                if (db.MakeConnection())
                {
                    databaseOk = true;
                }
                else
                {
                    MessageBox.Show("The application failed to connect with the database. You still can use the program but not see the history of the scanned clients.");
                    btnHistory.IsEnabled = false;
                }

            }
            catch (Exception ex)
            {
                log.WriteLine(applicationName, ex.Message);
            }
        }

        private void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            if (timer >= 0) 
            {
                lblStatus.Content = String.Format("Auto scan in: {0} seconds...", timer.ToString());
                timer--;                
            }
            else
            {
                timer = 180;
            }
        }

        private void btnRescan_MouseDown(object sender, MouseButtonEventArgs e)
        {
            ScanAvailableNetworks();
            timer = 180;
        }

        private void ScanAvailableNetworks()
        {
            try
            {
                UpdateConsole("Started scanning all the networks...");
                //ComboBox.Clear() also calls the cboxNetworkSSIDs_SelectionChanged(... , ...) method wich throws an error
                cboxNetworkSSIDs.Items.Clear();
                networkArray.Clear();
                countNetworks = 0;

                if (selectedWlanAdapter != null)
                {
                    //first clear the canvas
                    canvasRader.Children.Clear();

                    Wlan.WlanAvailableNetwork[] networks = selectedWlanAdapter.GetAvailableNetworkList(0);
                    foreach (Wlan.WlanAvailableNetwork n in networks)
                    {
                        Network network = new Network();

                        //enter all info:
                        if (GetStringForSSID(n.dot11Ssid).Length > 0)
                        {
                            network.SSID = GetStringForSSID(n.dot11Ssid);
                        }
                        else
                        {
                            network.SSID = "NO SSID";
                        }
                        if (!networkArray.Exists(o => o.SSID.Equals(network.SSID)))
                        {
                            network.MAC = "Not connected";
                            network.IP = "00.00.00.00";
                            network.FirstSeen = DateTime.Now;
                            network.LastSeen = DateTime.Now;
                            network.SignalStrength = selectedWlanAdapter.GetNetworkBssList(n.dot11Ssid, n.dot11BssType, n.securityEnabled)[0].rssi; //dBm
                            network.SignalQuality = Convert.ToInt16(n.wlanSignalQuality); //%
                            network.TypeOfSecurity = n.dot11DefaultAuthAlgorithm.ToString() + " || " + n.dot11DefaultCipherAlgorithm;


                            //check if network adapter is connected with a network
                            if (selectedWlanAdapter.InterfaceState == Wlan.WlanInterfaceState.Connected)
                            {
                                //check to wich network it is connected and get the gateway IP address
                                connectedSSID = GetStringForSSID(selectedWlanAdapter.CurrentConnection.wlanAssociationAttributes.dot11Ssid);
                                if (connectedSSID.Equals(network.SSID))
                                {
                                    network.IP = selectedWlanAdapter.NetworkInterface.GetIPProperties().GatewayAddresses[0].Address.ToString();
                                    foreach (UnicastIPAddressInformation x in selectedWlanAdapter.NetworkInterface.GetIPProperties().UnicastAddresses)
                                    {
                                        if (!x.IPv4Mask.ToString().Equals("0.0.0.0"))
                                        {
                                            selectedWlanAdapterSubnetMask = x.IPv4Mask;
                                        }
                                    }
                                    txtSubnetmask.Text = selectedWlanAdapterSubnetMask.ToString();
                                    network.MAC = ConvertWlanBssEntryToMac(selectedWlanAdapter.GetNetworkBssList()[0]);
                                    txtAdapterConnectedNetwork.Text = connectedSSID;
                                    txtAdapterSignalStrength.Text = network.SignalStrength.ToString() + " dBm";
                                    txtAdapterSignalQuality.Text = network.SignalQuality.ToString() + "%";
                                    btnDisconnect.IsEnabled = true;
                                    btnStartCapture.IsEnabled = true;
                                }
                            }

                            //draw the point on the radar
                            Ellipse circle = new Ellipse();
                            circle.Stroke = Brushes.Green;
                            circle.StrokeThickness = 2;
                            circle.Fill = Brushes.Black;
                            circle.Height = 8;
                            circle.Width = 8;

                            //transorm the drawingpoint
                            TranslateTransform move = new TranslateTransform();
                            /* Example:
                             * Signal strength is -90dBm (poor) so the point has to be futher away from the center.
                             * Signal strength is -24dBm (good) so the point has to be closer to the center.
                             */
                            double antennaX = (canvasRader.Width / 2) + (Math.Cos((random.NextDouble() * 360))) * (network.SignalStrength);
                            double antennaY = (canvasRader.Height / 2) + (Math.Sin((random.NextDouble() * 360))) * (network.SignalStrength);
                            move.X = antennaX;
                            move.Y = antennaY;
                            circle.RenderTransformOrigin = new Point(0.5, 0.5);
                            circle.RenderTransform = move;

                            //set a label
                            Label lblSSID = new Label();
                            lblSSID.Content = network.SSID;
                            lblSSID.FontSize = 8;
                            lblSSID.Foreground = Brushes.White;
                            lblSSID.Background = Brushes.Transparent;
                            move.X = antennaX + 2;
                            move.Y = antennaY - 5;
                            lblSSID.RenderTransformOrigin = new Point(0.0, 0.0);
                            lblSSID.RenderTransform = move;

                            //set a tooltip
                            ToolTip tool = new ToolTip();
                            tool.Content = network.SSID;
                            tool.HorizontalOffset = 15;
                            tool.VerticalOffset = -15;
                            ToolTipService.SetToolTip(circle, tool);
                            circle.Tag = network.SSID;

                            //finally add the circle and label to the canvas
                            canvasRader.Children.Add(circle);
                            canvasRader.Children.Add(lblSSID);

                            //add network SSID to combobox
                            cboxNetworkSSIDs.Items.Add(network.SSID);
                            countNetworks++;
                            networkArray.Add(network);
                        }
                    }//end for each

                    //set combobox value to network wich the adapter is connected to, if NULL then just set the first value
                    //if (connectedSSID == null)
                    //{
                    //    cboxNetworkSSIDs.SelectedIndex = 0;
                    //}
                    //else
                    //{
                    //    cboxNetworkSSIDs.SelectedValue = connectedSSID;
                    //    cboxNetworkSSIDs_SelectionChanged(this, null);
                    //}
                }
                else
                {
                    UpdateConsole("You have not selected a WLAN adapter yet or it is turned off.");
                }
                lblNetworks.Content = String.Format("Networks ({0}): ", countNetworks.ToString());
                UpdateConsole("Ended scanning for the available networks.");
            }
            catch (Exception ex)
            {
                UpdateConsole(ex.Message);
                log.WriteLine(applicationName, ex.Message);
            }//end exception
        }

        private void cboxNetworkSSIDs_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                selectedSSID = cboxNetworkSSIDs.SelectedValue.ToString();
                Network info = networkArray.Find(o => o.SSID.Equals(selectedSSID));
                txtNetworkFirstseen.Text = info.FirstSeen.ToString();
                txtNetworkLastseen.Text = info.LastSeen.ToString();
                txtNetworkSecurity.Text = info.TypeOfSecurity.ToString();
                txtNetworkSignalStrength.Text = info.SignalStrength.ToString() + " dBm";
                txtNetworkSignalQuality.Text = info.SignalQuality.ToString() + "%";
                txtNetworkIP.Text = info.IP.ToString();
                txtNetworkSSID.Text = info.SSID.ToString();
                txtNetworkMac.Text = info.MAC.ToString();
            }
            catch (Exception ex)
            {
                UpdateConsole(ex.Message);
                log.WriteLine(applicationName, ex.Message);
            }
        }

        private String ConvertMacToColons(String mac)
        {
            String m1 = mac.Substring(0, 2).ToUpper();
            String m2 = mac.Substring(2, 2).ToUpper();
            String m3 = mac.Substring(4, 2).ToUpper();
            String m4 = mac.Substring(6, 2).ToUpper();
            String m5 = mac.Substring(8, 2).ToUpper();
            String m6 = mac.Substring(10, 2).ToUpper();
            return m1 + ":" + m2 + ":" + m3 + ":" + m4 + ":" + m5 + ":" + m6;
        }

        private String ConvertWlanBssEntryToMac(Wlan.WlanBssEntry wlanbssentry)
        {
            byte[] macAddr = wlanbssentry.dot11Bssid;
            var macAddrLen = (uint)macAddr.Length;
            var str = new string[(int)macAddrLen];
            for (int i = 0; i < macAddrLen; i++)
            {
                str[i] = macAddr[i].ToString("x2");
            }
            return ConvertMacToColons(string.Join("", str));
        }

        private void cboxAdapters_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try 
            {
                selectedWlanAdapter = adapterArray[cboxAdapters.SelectedIndex];
                //get local adapter info and display them
                txtAdapterName.Text = selectedWlanAdapter.NetworkInterface.Name.ToString();
                txtAdapterMac.Text = ConvertMacToColons(selectedWlanAdapter.NetworkInterface.GetPhysicalAddress().ToString());
                if (selectedWlanAdapter.NetworkInterface.OperationalStatus.ToString().Equals("Up"))
                {
                    txtAdapterIp.Text = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();
                }
                else
                {
                    txtAdapterIp.Text = "-";
                }

                dispatcherTimer.Start();

                //do a first scan
                ScanAvailableNetworks();
            }
            catch (Exception ex)
            {
                UpdateConsole(ex.Message);
                log.WriteLine(applicationName, ex.Message);
            }
        }

        private void btnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            draad = new Thread(ScanPacketsOnNetwork);
            draad.Start();
            //ScanPacketsOnNetwork();
            countSecondsScanning = 0;
            packetTimer.Tick += new EventHandler(packetTimer_Tick);
            packetTimer.Interval = new TimeSpan(0, 0, 1);
            packetTimer.Start();

            dispatcherTimer.Stop();

            imgScanning.Visibility = Visibility.Visible;
            btnStopCapture.IsEnabled = true;
            btnStartCapture.IsEnabled = false;
        }

        private void packetTimer_Tick(object sender, EventArgs e)
        {
            countSecondsScanning++;
            lblPPS.Content = ((communicator.TotalStatistics.PacketsReceived + communicator.TotalStatistics.PacketsDroppedByInterface) / countSecondsScanning).ToString();
            lblPacketsRecieved.Content = communicator.TotalStatistics.PacketsReceived.ToString();
            lblPacketsDropped.Content = communicator.TotalStatistics.PacketsDroppedByInterface.ToString();
            TimeSpan t = TimeSpan.FromSeconds(countSecondsScanning);
            lblSeconds.Content = string.Format("{0:D2}:{1:D2}:{2:D2}", t.Hours, t.Minutes, t.Seconds);
            lblBytes.Content = (countPacketBytes / 1024).ToString() + "KB";
        }

        private void ScanPacketsOnNetwork()
        {
            try
            {
                UpdateConsole("Started capturing all packets on the network.");                

                if (selectedWlanAdapter.CurrentConnection.isState == Wlan.WlanInterfaceState.Connected)
                {
                    /* Work with SharpPcap here */
                    // Retrieve the device list
                    IList<LivePacketDevice> devices = LivePacketDevice.AllLocalMachine;
                    foreach (LivePacketDevice x in devices)
                    {
                        if (x.Name.Contains(selectedWlanAdapter.InterfaceGuid.ToString().ToUpper()))
                        {
                            sniffAdapter = x;
                            break;
                        }
                    }
                    //Promiscious: except ALL packets
                    //65536: guarantees that the whole packet will be captured on all the link layers
                    //0: no read time out
                    communicator = sniffAdapter.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000);
                    // start the capture
                    communicator.ReceivePackets(maximumPacketsToCapture, PacketHandler);
                }
                else
                {
                    UpdateConsole("Your not connected to the network, you can not scan it.");
                }
            }
            catch (Exception ex)
            {
                UpdateConsole(ex.Message);
                log.WriteLine(applicationName, ex.Message);
            }
        }

        private void btnStopCapture_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                imgScanning.Visibility = Visibility.Hidden;
                btnStopCapture.IsEnabled = false;
                btnStartCapture.IsEnabled = true;
                draad.Abort();
                UpdateConsole("Stopped capturing all packets on the network.");
                packetTimer.Stop();
                dispatcherTimer.Start();
                if (databaseOk)
                {
                    //finally save all the clients to the database
                    DataTable temp = (DataTable)CollectionHelper.ConvertTo(clientsArray);
                    temp.TableName = "tblClient";
                    if (db.UpdateFromDataTable(temp))
                    {
                        UpdateConsole("Updated the database.");
                    }
                }
            }
            catch (Exception ex)
            {
                UpdateConsole("Unable to stop the scan.");
                log.WriteLine(applicationName, ex.Message);
            }
        }

        public void PacketHandler(Packet packet)
        {
            try
            {
                
                countPacketBytes += packet.Length;
                IpV4Datagram ip = packet.Ethernet.IpV4;
                EthernetDatagram et = packet.Ethernet;

                if ((ip != null) && (et != null))
                {
                    //first check if the IP of the packet is in the range of the connected network
                    IPAddress connectedNetworkIP = selectedWlanAdapter.NetworkInterface.GetIPProperties().GatewayAddresses[0].Address;
                    IPAddress networkID = IPAddressExtensions.GetNetworkAddress(connectedNetworkIP, selectedWlanAdapterSubnetMask);
                    if (IPAddressExtensions.IsInSameSubnet(IPAddress.Parse(ip.Source.ToString()), connectedNetworkIP, networkID))
                    {
                        if (clientsArray.Exists(o => o.IP.Equals(ip.Source.ToString())))
                        {
                            int index = clientsArray.FindIndex(o => o.IP.Equals(ip.Source.ToString()));
                            Client client = new Client();
                            client = clientsArray[index];
                            client.LastSeen = DateTime.Now;
                            client.ConnectionTimeInSeconds = client.LastSeen.Subtract(client.FirstSeen).Seconds;
                            clientsArray.RemoveAt(index);
                            clientsArray.Add(client);
                        }
                        //add the new client to the array
                        else
                        {
                            Client client = new Client();
                            client.SSID = connectedSSID;
                            client.IP = ip.Source.ToString();
                            client.MAC = et.Source.ToString();
                            client.FirstSeen = DateTime.Now;
                            client.LastSeen = DateTime.Now;
                            client.ConnectionTimeInSeconds = 0;
                            try
                            {
                                IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
                                client.Domain = computerProperties.DomainName;
                                if (client.Domain == "")
                                {
                                    client.Domain = "NO DOMAIN";
                                }
                            }
                            catch (Exception)
                            {
                                client.Domain = "NO DOMAIN";
                            }
                            try
                            {
                                client.Hostname = Dns.GetHostByAddress(client.IP).HostName.ToString();
                            }
                            catch (Exception)
                            {

                                client.Hostname = "NO HOSTNAME";
                            }
                            clientsArray.Add(client);
                        }

                        lstClients.Dispatcher.Invoke(
                            DispatcherPriority.Normal,
                            (ThreadStart)delegate
                            {
                                lstClients.ItemsSource = null;
                                lstClients.ItemsSource = clientsArray;
                            }
                        );
                    }
                }

            }//end try
            catch (Exception ex)
            {
                UpdateConsole(ex.Message);
                log.WriteLine(applicationName, ex.Message);
            }
        }//end snifAdapter_OnPacketArrival

        public void UpdateConsole(String msg)
        {
            lstConsole.Dispatcher.Invoke(
                    DispatcherPriority.Normal,
                    (ThreadStart)delegate
                    {
                        lstConsole.Items.Add(DateTime.Now + ": " + msg);
                    }
            );
        }

        private void btnDisconnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (selectedWlanAdapter.CurrentConnection.isState == Wlan.WlanInterfaceState.Connected)
                {
                    if (draad != null)
                    {
                        if (draad.IsAlive)
                        {
                            btnStopCapture_Click(this, null); 
                        }
                    }
                    selectedWlanAdapter.Disconnect();
                    btnStartCapture.IsEnabled = false;
                    btnStopCapture.IsEnabled = false;
                    btnDisconnect.IsEnabled = false;
                    btnConnect.IsEnabled = true;
                    UpdateConsole("Disconnected from the network.");
                    
                    //reset adapter properties
                    txtAdapterConnectedNetwork.Text = "-";
                    txtAdapterIp.Text = "-";
                    txtAdapterMac.Text = "-";
                    txtAdapterName.Text = "-";
                    txtAdapterSignalQuality.Text = "-";
                    txtAdapterSignalStrength.Text = "-";
                }                
            }
            catch (Exception ex)
            {
                UpdateConsole("Unable to disconnect from the current network. Are you even connected?");
                log.WriteLine(applicationName, ex.Message);
            }
            finally
            {
                cboxAdapters_SelectionChanged("btnDisconnect", null);
            }
         }        

        public static bool IsApplictionInstalled(string p_name)
        {
            RegistryKey key;

            // search in: CurrentUser
            key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            foreach (String keyName in key.GetSubKeyNames())
            {
                RegistryKey subkey = key.OpenSubKey(keyName);
                if (subkey.Name.ToString().ToUpper().EndsWith(p_name.ToUpper()))
                {
                    return true;
                }
            }

            // search in: LocalMachine_32
            key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            foreach (String keyName in key.GetSubKeyNames())
            {
                RegistryKey subkey = key.OpenSubKey(keyName);
                if (subkey.Name.ToString().ToUpper().EndsWith(p_name.ToUpper()))
                {
                    return true;
                }
            }

            // search in: LocalMachine_64
            key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
            foreach (String keyName in key.GetSubKeyNames())
            {
                RegistryKey subkey = key.OpenSubKey(keyName);
                if (subkey.Name.ToString().ToUpper().EndsWith(p_name.ToUpper()))
                {
                    return true;
                }
            }

            // NOT FOUND
            return false;
        }

        private void lstClients_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (MessageBox.Show("Want to print the contents of the gathered information?", "Print dialog", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
            {
                PrintDialog printDlg = new PrintDialog();
                printDlg.PrintVisual(lstClients, "Printing.");
            }
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //get all the saved network profiles and save them to "profileArray";
                Wlan.WlanProfileInfo[] profiles = selectedWlanAdapter.GetProfiles();
                foreach (Wlan.WlanProfileInfo profile in profiles)
                {
                    profileArray.Add(profile.profileName);
                }
                foreach (String profileName in profileArray)
                {
                    if (profileName.Equals(selectedSSID))
                    {
                        //String xmlProfile = selectedWlanAdapter.GetProfileXml(profileName);
                        selectedWlanAdapter.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, selectedSSID);
                    }
                }
                System.Threading.Thread.Sleep(1000);
                if (selectedWlanAdapter.InterfaceState == Wlan.WlanInterfaceState.Connected)
                {
                    UpdateConsole("Connected to the selected network.");
                    btnDisconnect.IsEnabled = true;
                    btnConnect.IsEnabled = false;
                    cboxAdapters_SelectionChanged(this, null);
                }
                else
                {
                    UpdateConsole("Unable to connect to the selected network.");
                }
            }
            catch (Exception ex)
            {
                UpdateConsole("Unable to connect to the selected network.");
                log.WriteLine(applicationName, ex.Message);
            }
        }

        private void btnHistory_Click(object sender, RoutedEventArgs e)
        {
            //open up the "History window"
            var newWindow = new History();
            newWindow.ShowDialog();
        }
    }//end class MainWindow : Window
}//end namespace
